package com.xuemeng.config;


import com.xuemeng.util.MyMapper;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;


/**
 * @author <a href="xuemeng"></a>
 * @version 1.0, 2017/11/24
 * @description
 */
@Configuration
// 精确到 mapper 目录，以便跟其他数据源隔离
@MapperScan(basePackages = "com.xuemeng.mapper", markerInterface = MyMapper.class, sqlSessionFactoryRef = "sqlSessionFactory")
public class MybatisDatasourceConfig {

        @Autowired
        @Qualifier("dataSource")
        private DataSource ds;

        @Bean
        public SqlSessionFactory sqlSessionFactory() throws Exception {
                SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
                factoryBean.setDataSource(ds);
                //指定mapper xml目录
                ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
                factoryBean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
                return factoryBean.getObject();

        }

        @Bean
        public SqlSessionTemplate sqlSessionTemplate() throws Exception {
                SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory()); // 使用上面配置的Factory
                return template;
        }

        //关于事务管理器，不管是JPA还是JDBC等都实现自接口 PlatformTransactionManager
        // 如果你添加的是 spring-boot-starter-jdbc 依赖，框架会默认注入 DataSourceTransactionManager 实例。
        //在Spring容器中，我们手工注解@Bean 将被优先加载，框架不会重新实例化其他的 PlatformTransactionManager 实现类。
        @Bean(name = "transactionManager")
        @Primary
        public DataSourceTransactionManager masterTransactionManager() {
                //MyBatis自动参与到spring事务管理中，无需额外配置，只要org.mybatis.spring.SqlSessionFactoryBean引用的数据源
                // 与DataSourceTransactionManager引用的数据源一致即可，否则事务管理会不起作用。
                return new DataSourceTransactionManager(ds);

        }

}
